local DB = require("common.DB")
local LuaMongo = _G.lua_mongo
local Human = require("core.Human")
local RoleFFI  = require("role.RoleFFI")
local ShopHelp = require("shop.ShopHelp")

local QueryByAccount = {}		--按帐号查询
local QueryByName = {}			--按角色名查询
local QueryByUuid = {}			--按uuid查询
local QueryUpdateChar = {}

local data = {}
local f = {name = 1}
function isNameExistInDB(name)
    QueryByName.name = name
    LuaMongo.find(DB.db_char, QueryByName, f)
    return LuaMongo.next(data) and data
end

function delName(name)
    QueryByName.name = name
    LuaMongo.remove(DB.db_char, QueryByName)
end

-- 跨服异常专用 其他任何地方别调用 谨慎
function delAccount(account)
    QueryByAccount.account = account
    LuaMongo.remove(DB.db_char, QueryByAccount)
end

local f = {}
function getDbByName(name, fields)
    local t = Human.onlineHuman[name]
    if t then
        local db = RoleFFI.get_default_db()
        RoleFFI.copy_ffi_to_db(t.db, db)
        return db
    end
    QueryByName.name = name
    local data = {}
    if type(fields) == "string" then
        local k = next(f)
        if k then
            f[k] = nil
        end
        f[fields] = 1
        fields = f
    end
    LuaMongo.find(DB.db_char, QueryByName, fields)
    return LuaMongo.next(data) and data
end

function getDbByUuid(uuid, fields)
    local t = Human.onlineUuid[uuid]
    if t then
        local db = RoleFFI.get_default_db()
        RoleFFI.copy_ffi_to_db(t.db, db)
        return db
    end
    QueryByUuid._id = uuid
    local data = {}
    if type(fields) == "string" then
        local k = next(f)
        if k then
            f[k] = nil
        end
        f[fields] = 1
        fields = f
    end
    LuaMongo.find(DB.db_char, QueryByUuid, fields)
    return LuaMongo.next(data) and data
end

function getDbByAccount(account, fields)
    local t = Human.onlineAccount[account]
    if t then
        local db = RoleFFI.get_default_db()
        RoleFFI.copy_ffi_to_db(t.db, db)
        return db
    end
    QueryByAccount.account = account
    local data = {}
    if type(fields) == "string" then
        local k = next(f)
        if k then
            f[k] = nil
        end
        f[fields] = 1
        fields = f
    end
    LuaMongo.find(DB.db_char, QueryByAccount, fields)
    return LuaMongo.next(data) and data
end

local data = {}
local f = {account = 1,middleFlag = 1}
function isAccountExistInDB(account)
    QueryByAccount.account = account
    data.account = nil
    data.middleFlag = nil
    LuaMongo.find(DB.db_char, QueryByAccount, f)
    if not LuaMongo.next(data) then
        return
    end
    return true,data
end

local data2 = {}
local f2 = {account = 1}
function getUuidByAccount(account)
    QueryByAccount.account = account
    LuaMongo.find(DB.db_char, QueryByAccount, f2)
    if not LuaMongo.next(data2) then
        return
    end
    return data2._id
end

-- 这个函数跨服用来读取数据 非常重要 不要随便改
function isUuidExistInDB(uuid)
    QueryByUuid._id = uuid
    local data = {}
    LuaMongo.find(DB.db_char, QueryByUuid)
    if not LuaMongo.next(data) then
        return
    end
    return true,data
end

function createDefaultRole(account, roleName, sex)--, gm)
    local db = RoleFFI.get_default_db()
    db.account = account
    db.name    = roleName
    db.sex     = sex
    if sex == 1 then
        db.head = 1001
    else
        db.head = 1002
    end
    db._id     = nil
    --    db.lastLogoutTime = os.time()
    LuaMongo.insert(DB.db_char, db)
    print("db._id", db._id)
    return db
end

function loadRole(account)
    QueryByAccount.account = account
    local data = {}
    LuaMongo.find(DB.db_char, QueryByAccount)
    if LuaMongo.next(data) then
        return data
    end
end

local function check_key_table(db, fa)
    fa = fa or "db"
    for k, v in pairs(db) do
        if type(k) == "table" then
            assert(nil, "fa:" ..fa .. "\n" .. require("common.Util").printTable(k))
        end
        if type(v) == "table" then
            check_key_table(v, fa .. "---" .. k)
        end
    end
end

function saveRole(db)
    QueryUpdateChar._id = db._id
    --check_key_table(db)
    LuaMongo.update(DB.db_char, QueryUpdateChar, db)
end

local tb = {}
function saveRoleSset(set, sunset)
    if not set._id then
        return
    end
    QueryUpdateChar._id = set._id
    set._id = nil
    tb["$set"] = set 
    tb["$unset"] = sunset
    LuaMongo.update(DB.db_char, QueryUpdateChar, tb)
    set._id = QueryUpdateChar._id
end

local fields = {name=1}
function getNameByUuid(uuid)
    if Human.onlineUuid[uuid] ~= nil then
        return Human.onlineUuid[uuid].db.name
    else
        QueryByUuid._id = uuid
        local data = {}
        LuaMongo.find(DB.db_char, QueryByUuid, fields)
        if not LuaMongo.next(data) then
            return nil
        end
        return data.name
    end
end

local query = {}
local f = {}
function getDb(uuid, fields)
    local t = Human.onlineUuid[uuid]
    if t then
        --local nData = {}
        --RoleFFI.copy_ffi_to_db(t.db, nData, fields)
        --return nData
        return t.db
    end
    query._id = uuid
    local data = {}
    if type(fields) == "string" then
        local k = next(f)
        if k then
            f[k] = nil
        end
        f[fields] = 1
        fields = f
    end
    LuaMongo.find(DB.db_char, query, fields)
    return LuaMongo.next(data) and data
end


-- 每次新增增加字段
-- 如果修改已有数组再加字段，则加为 oldKey = {child_template={ old1, old2, new1}}
local newAddDBData = {
    skillItemList = {[0] = 0, 0},
    officialTarget = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --军衔已完成的目标
    officialRewardIsGet = 0, --军衔日常奖励是否领取
    officialLv = 0, --军衔等级
    armourlist  = {child_template={armourid = 0, lv = 0, star = 0, state = 1, feedAttr={[0]=0,0,0,0,0,0,0,0}}},  --战甲列表
}

local roleDBchanged
local function handleNew(orgDB, newTable)
    for k, v in pairs(newTable) do
        if type(v) == "table" and v.child_template then --数组
            if not orgDB[k] then 
                orgDB[k] = {}  --新增数组
            end
            if not orgDB[k.."Len"] then
                orgDB[k.."Len"] = newTable[k.."Len"]
            end           
            for i = 0, orgDB[k.."Len"] - 1 do  --修改数组
                if not orgDB[k][i] then
                    orgDB[k][i] = {}
                end
                handleNew(orgDB[k][i], v.child_template)
            end
        elseif not orgDB[k] then --新增非数组
            orgDB[k] = v
            roleDBchanged = true
        elseif type(v) == "table" then --递归
            handleNew(orgDB[k],v)
        end
    end
end

function roleDBInit()
    local modify
    for k,v in pairs(newAddDBData) do
        modify = true
        break
    end
    if not modify then
        --        return
    end
    LuaMongo.find(DB.db_char, {})
    local list = {}
    local all = 0
    while true do
        local data = {}
        if not LuaMongo.next(data) then
            break
        end
        all = all + 1
        roleDBchanged = nil
        handleNew(data, newAddDBData)
        if roleDBchanged then
            list[#list + 1] = data._id
        end
    end
    print("roleDBInit:", #list, "/", all)
    local query = {}
    for _, v in ipairs(list) do
        query._id = v
        LuaMongo.find(DB.db_char, query)
        local data = {}
        if not LuaMongo.next(data) then
            assert()
        end
        roleDBchanged = nil
        handleNew(data, newAddDBData)
        if not roleDBchanged then
            assert()
        end

        --print(data._id, data.account, data.name)
        LuaMongo.update(DB.db_char, query, data)
    end
end
